﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Job.cs" company="DHGMS Solutions">
//   Copyright 2004-2014 DHGMS Solutions.
//      
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//      
//   http://www.apache.org/licenses/LICENSE-2.0
//      
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
// </copyright>
// <summary>
//   The job.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Dhgms.TplHelper.Model.ProviderProxy
{
    using System;
    using System.Configuration.Provider;

    using Dhgms.DataManager.Model.ConfigurationSection;
    using Dhgms.TplHelper.Model.Info.JobResult;
    using Dhgms.TplHelper.Model.Provider.Job;

    /// <summary>
    /// The job.
    /// </summary>
    /// <typeparam name="TJobResultClass">
    /// </typeparam>
    internal class Job<TJobResultClass> : Dhgms.DataManager.Model.ProviderProxy.Base<Job<TJobResultClass>, JobMonitoringBase<TJobResultClass>, Dhgms.DataManager.Model.ProviderCollection.BaseCollection<JobMonitoringBase<TJobResultClass>>, ProviderSection>
        where TJobResultClass : Base, new()
    {
        #region Constructors and Destructors

        private readonly Lazy<Provider.Job.EventLog<TJobResultClass>> lazyEventLogProvider = new Lazy<Provider.Job.EventLog<TJobResultClass>>(() => new EventLog<TJobResultClass>());

        /// <summary>
        /// Initializes a new instance of the <see cref="Job{TJobResultClass}"/> class. 
        /// </summary>
        public Job()
            : base("job")
        {
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// Output the failure information
        /// </summary>
        /// <param name="programGuid">
        /// The Program Unique ID
        /// </param>
        /// <param name="programName">
        /// The Program Friendly Name
        /// </param>
        /// <param name="runId">
        /// The Unique ID of the current run
        /// </param>
        /// <param name="e">
        /// The exception to report
        /// </param>
        public void OnJobFailure(Guid programGuid, string programName, int runId, Exception e)
        {
            try
            {
                var instance = new Job<TJobResultClass>();
                instance.LoadProviders();

                if (this.Providers == null)
                {
                    return;
                }

                foreach (JobMonitoringBase<TJobResultClass> prov in Providers)
                {
                    try
                    {
                        prov.OnJobFailure(programGuid, programName, e);
                    }

                    // ReSharper disable EmptyGeneralCatchClause
                    catch
                    // ReSharper restore EmptyGeneralCatchClause
                    {
                    }
                }
            }
            // ReSharper disable EmptyGeneralCatchClause
            catch
            // ReSharper restore EmptyGeneralCatchClause
            {
            }

            this.lazyEventLogProvider.Value.OnJobFailure(programGuid, programName, e);
        }

        /// <summary>
        /// Notify the provider of a job start
        /// </summary>
        /// <param name="programGuid">
        /// The program Guid.
        /// </param>
        public void OnJobStart(Guid programGuid)
        {
            var instance = new Job<TJobResultClass>();
            instance.LoadProviders();
            if (this.Providers == null)
            {
                throw new ProviderException("provider not found");
            }

            foreach (JobMonitoringBase<TJobResultClass> prov in Providers)
            {
                try
                {
                    prov.OnJobStart(programGuid);
                }

                    // ReSharper disable EmptyGeneralCatchClause
                catch
                {
                    // ReSharper restore EmptyGeneralCatchClause
                }
            }
        }

        /// <summary>
        /// Outputs job result information to all providers
        /// </summary>
        /// <param name="programGuid">
        /// The Program Unique ID
        /// </param>
        /// <param name="programName">
        /// The Program Friendly Name
        /// </param>
        /// <param name="taskResult">
        /// The Job Results
        /// </param>
        public void OnJobSucess(Guid programGuid, string programName, TJobResultClass taskResult)
        {
            var instance = new Job<TJobResultClass>();
            instance.LoadProviders();

            if (this.Providers == null)
            {
                return;
            }

            foreach (JobMonitoringBase<TJobResultClass> prov in Providers)
            {
                try
                {
                    prov.OnJobSucess(programGuid, programName, taskResult);
                }
                    
                    // ReSharper disable EmptyGeneralCatchClause
                catch
                {
                    // ReSharper restore EmptyGeneralCatchClause
                }
            }
        }

        /// <summary>
        /// Register the Job with the providers
        /// This is so some providers can act on the first run of a job
        /// </summary>
        /// <param name="programGuid">
        /// The program Guid.
        /// </param>
        /// <param name="programName">
        /// The program Name.
        /// </param>
        public void Register(Guid programGuid, string programName)
        {
            foreach (JobMonitoringBase<TJobResultClass> prov in Providers)
            {
                try
                {
                    //prov.OnRegister(programGuid, programName);
                }

                    // ReSharper disable EmptyGeneralCatchClause
                catch
                {
                    // ReSharper restore EmptyGeneralCatchClause
                }
            }
        }

        #endregion
    }
}